﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Net;
using System.Xml.Linq;
using System.IO;
using System.Data;

namespace MyGMaps
{
    public partial class _Default : System.Web.UI.Page
    {
        private static string user = null;
        private static int pointID = -1;

        protected void Page_Load(object sender, EventArgs e)
        {
            GoogleMapForASPNet1.MapClicked += new GoogleMapForASPNet.MapClickedHandler(OnMapClicked);
            GoogleMapForASPNet1.PushpinClicked += new GoogleMapForASPNet.PushpinClickedHandler(OnPushpinClicked);
            GoogleMapForASPNet1.PushpinDrag += new GoogleMapForASPNet.PushpinDragHandler(OnPushpinDraged);

            // Thiết lập...
            lbl_ThongBao.Text = "";

            if (!IsPostBack)
            {
                btn_DangNhap.Enabled = true;
                btn_DangXuat.Enabled = false;
                ibt_FindNearService.Enabled = false;
                Save.Enabled = false;
                Update.Enabled = false;
                
               

                //You must specify Google Map API Key for this component. You can obtain this key from http://code.google.com/apis/maps/signup.html
                //For samples to run properly, set GoogleAPIKey in Web.Config file.
                GoogleMapForASPNet1.GoogleMapObject.APIKey = ConfigurationManager.AppSettings["GoogleAPIKey"];

                //Specify width and height for map. You can specify either in pixels or in percentage relative to it's container.
                GoogleMapForASPNet1.GoogleMapObject.Width = "640px"; // You can also specify percentage(e.g. 80%) here
                GoogleMapForASPNet1.GoogleMapObject.Height = "500px";

                //Specify initial Zoom level.
                GoogleMapForASPNet1.GoogleMapObject.ZoomLevel = 6;

                //Specify Center Point for map. Map will be centered on this point.
                GoogleMapForASPNet1.GoogleMapObject.CenterPoint = new GooglePoint("1", 10.8230989, 106.6296638);

            }
        }

        //Add event handler for Map Click event
        void OnMapClicked(double dLat, double dLng)
        {
            //Generate new id for google point
            string sID = (GoogleMapForASPNet1.GoogleMapObject.Points.Count + 1).ToString();
            string IconImage = "icons/pushpin-blue.png";
            string InfoHTML = "Point ID: " + sID;

            GooglePoint GP1 = new GooglePoint(sID, dLat, dLng, IconImage, InfoHTML);
            GP1.Draggable = true;
            GP1.ToolTip = "Point ID: " + sID;


            GoogleMapForASPNet1.GoogleMapObject.Points.Add(GP1);
            tbx_ViDo.Text = dLat.ToString();
            tbx_TungDo.Text = dLng.ToString();
            tbx_TenDichVu.Text = sID;

            // Không cho người dùng cập nhật điểm vừa được chọn...
            pointID = -1;
            if (user != null)
                Save.Enabled = true;
            Update.Enabled = false;
        }

        void OnPushpinClicked(string pID)
        {
            tbx_ViDo.Text = GoogleMapForASPNet1.GoogleMapObject.Points[pID].Latitude.ToString();
            tbx_TungDo.Text = GoogleMapForASPNet1.GoogleMapObject.Points[pID].Longitude.ToString();
            tbx_TenDichVu.Text = pID;
        }

        void OnPushpinDraged(string pID)
        {
            tbx_ViDo.Text = GoogleMapForASPNet1.GoogleMapObject.Points[pID].Latitude.ToString();
            tbx_TungDo.Text = GoogleMapForASPNet1.GoogleMapObject.Points[pID].Longitude.ToString();
            tbx_TenDichVu.Text = pID;
        }


        /// <summary>
        /// Chức năng tìm kiếm...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnSearch_Click(object sender, EventArgs e)
        {
            // refresh map cho lần search tiếp theo
            GoogleMapForASPNet1.GoogleMapObject.Points.Clear();

            // Reset bảng kết quả...
            GridView1.DataSource = null;
            GridView1.DataBind();

            string address = TextSearch.Text;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=true");
            request.Method = "GET";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());

            XDocument data = XDocument.Load(sr);
            var status = from c in data.Descendants("status")
                         select c.Value;


            DataTable tb = new DataTable();
            DataRow dr = null;

            tb.Columns.Add("SearchResult", typeof(string));

            if (status.Contains("OK"))
            {

                var TenDiaDiem = (from c in data.Descendants("result")
                                  select c.Element("formatted_address").Value).ToArray();

                var lat = (from b in data.Descendants("location")
                           select b.Element("lat").Value).ToArray();

                var lng = (from b in data.Descendants("location")
                           select b.Element("lng").Value).ToArray();

                int count = TenDiaDiem.Count();



                if (lat.Count() == count && lng.Count() == count)
                {
                    for (int i = 0; i < count; i++)
                    {
                        dr = tb.NewRow();
                        dr["SearchResult"] = TenDiaDiem[i];

                        tb.Rows.Add(dr);


                        //Tạo 1 point trên bản đồ ứng với mỗi kết quả
                        GoogleMapForASPNet1.GoogleMapObject.ZoomLevel = 6;

                        GooglePoint GP1 = new GooglePoint(TenDiaDiem[i], Double.Parse(lat[i]), Double.Parse(lng[i]));

                        GP1.ToolTip = TenDiaDiem[i];
                        GoogleMapForASPNet1.GoogleMapObject.Points.Add(GP1);

                    }
                }

                GridView1.DataSource = tb;
                GridView1.DataBind();
            }
        }


        /// <summary>
        /// Chức năng hiển thị điểm tìm kiếm lên bản đồ trong GridView kết quản tìm kiếm...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            GridViewRow row = GridView1.SelectedRow;

            string address = HttpUtility.HtmlDecode(row.Cells[1].Text.ToString());

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=true");
            request.Method = "GET";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());

            XDocument data = XDocument.Load(sr);
            var status = from c in data.Descendants("status")
                         select c.Value;

            if (status.Contains("OK"))
            {

                var TenDiaDiem = (from c in data.Descendants("result")
                                  select c.Element("formatted_address").Value).ToArray();

                var lat = (from b in data.Descendants("location")
                           select b.Element("lat").Value).ToArray();

                var lng = (from b in data.Descendants("location")
                           select b.Element("lng").Value).ToArray();

                //Xóa các point khác. để chỉ hiện mỗi point được chọn
                GoogleMapForASPNet1.GoogleMapObject.Points.Clear();

                //tạo đối tượng Point với thông tin được chọn
                GooglePoint GP1 = new GooglePoint(address, Double.Parse(lat[0]), Double.Parse(lng[0]));

                //zoom bản đồ
                GoogleMapForASPNet1.GoogleMapObject.ZoomLevel = 10;

                //------Thêm các thông tin cho point
                GP1.IconImage = "icons/pushpin-yellow.png";
                GP1.ToolTip = address;
                GP1.InfoHTML = address;


                //----đưa point lên bản đồ
                GoogleMapForASPNet1.GoogleMapObject.Points.Add(GP1);

                //----- cho point này trở thành point trung tâm của bản đồ
                GoogleMapForASPNet1.GoogleMapObject.CenterPoint = GP1;
                GoogleMapForASPNet1.GoogleMapObject.RecenterMap = true;

                // Hiển thị thông tin địa điểm lên bảng thông tin...
                tbx_ViDo.Text = lat[0]; // Vi do...
                tbx_TungDo.Text = lng[0]; // Tung do...
                tbx_TenDichVu.Text = address; // Tên dịch vụ...
            }

            // Không cho người dùng cập nhật thông tin  của điểm mới được tìm thấy...
            pointID = -1;
            if (user != null)
                Save.Enabled = true;
            Update.Enabled = false;
        }


        /// <summary>
        /// Chức năng Đăng nhập...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btn_DangNhap_Click(object sender, EventArgs e)
        {
            user = tbx_Username.Text.ToString();
            string pass = tbx_Pass.Text.ToString();
            DataView tk = (DataView)ADS_TaiKhoan.Select(DataSourceSelectArguments.Empty);
            int index = -1;
            int count = tk.Count;
            for (int i = 0; i < count; i++)
            {
                if (tk.Table.Rows[i][0].ToString() == user)
                    if (tk.Table.Rows[i][1].ToString() == pass)
                    {
                        index = 1;

                        break;
                    }
            }

            if (index == 1)
            {
                tbx_Username.Enabled = false;
                tbx_Pass.Enabled = false;

                btn_DangNhap.Enabled = false;
                btn_DangXuat.Enabled = true;
                ibt_FindNearService.Enabled = true;
                lbl_Alert.Text = "Chào " + user + "!";

                Save.Enabled = true;
                Update.Enabled = true;
            }
            else
            {
                user = null;
                lbl_Alert.Text = "Đăng nhập thất bại! Mời bạn đăng nhập lại!";
            }
        }


        /// <summary>
        /// Chức năng Đăng xuất...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btn_DangXuat_Click(object sender, EventArgs e)
        {
            user = null;
            tbx_Username.Enabled = true;
            tbx_Username.Text = "";
            tbx_Pass.Enabled = true;
            btn_DangNhap.Enabled = true;
            btn_DangXuat.Enabled = false;
            ibt_FindNearService.Enabled = false;
            

            lbl_Alert.Text = "";

            Save.Enabled = false;
            Update.Enabled = false;
        }


        /// <summary>
        /// Chức năng lưu lại địa điểm dịch vụ...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Save_Click(object sender, EventArgs e)
        {
            // Truyền tham số cho hàm Insert...
            ADS_DanhSachDiaDiem.InsertParameters["Username"].DefaultValue = user;
            ADS_DanhSachDiaDiem.InsertParameters["DichVu"].DefaultValue = ddl_LDV.Text.ToString();
            ADS_DanhSachDiaDiem.InsertParameters["TenDichVu"].DefaultValue = tbx_TenDichVu.Text.ToString();
            ADS_DanhSachDiaDiem.InsertParameters["ViDo"].DefaultValue = tbx_ViDo.Text.ToString();
            ADS_DanhSachDiaDiem.InsertParameters["TungDo"].DefaultValue = tbx_TungDo.Text.ToString();
            if (Share.Checked == true)
                ADS_DanhSachDiaDiem.InsertParameters["Share"].DefaultValue = "1";
            else
                ADS_DanhSachDiaDiem.InsertParameters["Share"].DefaultValue = "0";

            // Thực hiện chức năng Insert...
            try
            {
                if (ADS_DanhSachDiaDiem.Insert() == 1)
                {
                    lbl_ThongBao.Text = "Lưu thành công!...";
                }
                else
                {
                    lbl_ThongBao.Text = "Lưu thất bại!...";
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }


        /// <summary>
        /// Chức năng xóa địa điểm trên bản đồ (chỉ xóa điểm trên bản đồ, không xóa dữ liệu của địa điểm dịch vụ)...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btn_Xoa_Click(object sender, EventArgs e)
        {
            string sID = tbx_TenDichVu.Text;
            GoogleMapForASPNet1.GoogleMapObject.Points.Remove(sID);

            tbx_ViDo.Text = "";
            tbx_TungDo.Text = "";
            tbx_TenDichVu.Text = "";
        }


        /// <summary>
        /// Chức năng update thông tin của địa điểm dịch vụ...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Update_Click(object sender, EventArgs e)
        {
            // Truyền tham số cho hàm Update...
            ADS_DanhSachDiaDiem.UpdateParameters["Username"].DefaultValue = user;
            ADS_DanhSachDiaDiem.UpdateParameters["DichVu"].DefaultValue = ddl_LDV.Text.ToString();
            ADS_DanhSachDiaDiem.UpdateParameters["TenDichVu"].DefaultValue = tbx_TenDichVu.Text.ToString();
            ADS_DanhSachDiaDiem.UpdateParameters["ViDo"].DefaultValue = tbx_ViDo.Text.ToString();
            ADS_DanhSachDiaDiem.UpdateParameters["TungDo"].DefaultValue = tbx_TungDo.Text.ToString();
            ADS_DanhSachDiaDiem.UpdateParameters["PointID"].DefaultValue = pointID.ToString();
            if (Share.Checked == true)
                ADS_DanhSachDiaDiem.InsertParameters["Share"].DefaultValue = "1";
            else
                ADS_DanhSachDiaDiem.InsertParameters["Share"].DefaultValue = "0";
            // Thực hiện chức năng Update...
            try
            {
                if (ADS_DanhSachDiaDiem.Update() == 1)
                {
                    // Update thành công...
                    tbx_TenDichVu.Text = "";
                    tbx_ViDo.Text = "";
                    tbx_TungDo.Text = "";
                    lbl_ThongBao.Text = "Cập nhật thành công!...";
                }
                else
                {
                    // Update thất bại...
                    lbl_ThongBao.Text = "Cập nhật thất bại!...";
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }


        /// <summary>
        /// Hiển thị lên bản đồ điểm được chọn trong GridView...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void grw_DanhSachDiaDiem_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Select")
            {
                // Hiển thị thông tin địa điểm được chọn lên bảng thông tin.
                GridViewRow row = grw_DanhSachDiaDiem.Rows[Convert.ToInt32(e.CommandArgument)];
                tbx_TenDichVu.Text = HttpUtility.HtmlDecode(row.Cells[3].Text.ToString());
                tbx_ViDo.Text = row.Cells[4].Text.ToString();
                tbx_TungDo.Text = row.Cells[5].Text.ToString();

                pointID = int.Parse(row.Cells[0].Text.ToString());

                // Hiển thị điểm được chọn lên bản đồ...
                string address = HttpUtility.HtmlDecode(row.Cells[3].Text.ToString());
                string lat = row.Cells[4].Text.ToString();
                string lng = row.Cells[5].Text.ToString();


                GoogleMapForASPNet1.GoogleMapObject.Points.Clear();

                //tạo đối tượng Point với thông tin được chọn
                GooglePoint GP1 = new GooglePoint(address, Double.Parse(lat), Double.Parse(lng));

                //zoom bản đồ
                GoogleMapForASPNet1.GoogleMapObject.ZoomLevel = 10;

                //------Thêm các thông tin cho point
                GP1.IconImage = "icons/pushpin-yellow.png";
                GP1.ToolTip = address;
                GP1.InfoHTML = address;


                //----đưa point lên bản đồ
                GoogleMapForASPNet1.GoogleMapObject.Points.Add(GP1);

                //----- cho point này trở thành point trung tâm của bản đồ
                GoogleMapForASPNet1.GoogleMapObject.CenterPoint = GP1;
                GoogleMapForASPNet1.GoogleMapObject.RecenterMap = true;

                //
                Save.Enabled = false;
                Update.Enabled = true;
            }
        }


        /// <summary>
        /// Chức năng tìm kiếm dịch vụ gần vị trí của mình...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ibt_FindNearService_Click(object sender, ImageClickEventArgs e)
        {
            ibt_MyLocation_Click(sender, e);

            //DataView data = (DataView)ADS_DiaDiem.Select(DataSourceSelectArguments.Empty);
            DataView data = (DataView)ADS_DanhSachDiaDiem.Select(DataSourceSelectArguments.Empty);
            int count = data.Count;

            // Tạo một mảng lưu trữ khoảng cách.
            Double[] a = new Double[count];
            for (int i = 0; i < count; i++)
            {
                a[i] = Math.Sqrt((Double.Parse((data.Table.Rows[i][4].ToString())) -
                    Double.Parse(hdTempLat.Value.Trim())) *
                    (Double.Parse((data.Table.Rows[i][4].ToString())) -
                    Double.Parse(hdTempLat.Value.Trim())) +
                    (Double.Parse((data.Table.Rows[i][5].ToString())) -
                    Double.Parse(hdTempLng.Value.Trim())) *
                    (Double.Parse((data.Table.Rows[i][5].ToString())) -
                    Double.Parse(hdTempLng.Value.Trim())));
            }


            // Hiển thị các kết quả lên bảng kết quả...
            DataTable dt = new DataTable();
            DataRow dr = null;

            dt.Columns.Add("SearchResult", typeof(string));
            for (int i = 0; i < count - 1; i++)
            {
                for (int j = i; j < count; j++)
                {
                    if (a[i] > a[j])
                    {
                        // Hoán đổi mảng giá trị...
                        Double temp = a[i];
                        a[i] = a[j];
                        a[j] = temp;
                    }
                }
            }
            for (int i = 0; i < count; i++)
            {
                for (int j = 0; j < count; j++)
                {
                    if (a[i] == Math.Sqrt((Double.Parse((data.Table.Rows[j][4].ToString())) -
                    Double.Parse(hdTempLat.Value.Trim())) *
                    (Double.Parse((data.Table.Rows[j][4].ToString())) -
                    Double.Parse(hdTempLat.Value.Trim())) +
                    (Double.Parse((data.Table.Rows[j][5].ToString())) -
                    Double.Parse(hdTempLng.Value.Trim())) *
                    (Double.Parse((data.Table.Rows[j][5].ToString())) -
                    Double.Parse(hdTempLng.Value.Trim()))))
                    {
                        dr = dt.NewRow();
                        dr["SearchResult"] = data.Table.Rows[j][3].ToString();
                        dt.Rows.Add(dr);

                        //Tạo 1 point trên bản đồ ứng với mỗi kết quả
                        GoogleMapForASPNet1.GoogleMapObject.ZoomLevel = 6;

                        GooglePoint GP1 = new GooglePoint(data.Table.Rows[j][3].ToString(), Double.Parse(data.Table.Rows[j][4].ToString()), Double.Parse(data.Table.Rows[j][5].ToString()));

                        GP1.ToolTip = data.Table.Rows[j][3].ToString();
                        GoogleMapForASPNet1.GoogleMapObject.Points.Add(GP1);
                    }
                }
            }


            GridView1.DataSource = dt;
            GridView1.DataBind();
        }


        /// <summary>
        /// Chức năng tìm kiếm vị trí của mình...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ibt_MyLocation_Click(object sender, ImageClickEventArgs e)
        {

            string address = "Vị trí của bạn hiện tại.";
            Double lat = Double.Parse(hdTempLat.Value.Trim());
            Double lng = Double.Parse(hdTempLng.Value.Trim());

            GooglePoint GP1 = new GooglePoint(address, lat, lng);
            GP1.InfoHTML = address;
            GP1.IconImage = "icons/pushpin-yellow.png";

            GoogleMapForASPNet1.GoogleMapObject.Points.Add(GP1);
            GoogleMapForASPNet1.GoogleMapObject.ZoomLevel = 17;

            //----- cho point này trở thành point trung tâm của bản đồ
            GoogleMapForASPNet1.GoogleMapObject.CenterPoint = GP1;
            GoogleMapForASPNet1.GoogleMapObject.RecenterMap = true;

            // Hiển thị Vĩ độ và Tung độ lên bản đồ...
            tbx_TenDichVu.Text = address;
            tbx_ViDo.Text = hdTempLat.Value.Trim();
            tbx_TungDo.Text = hdTempLng.Value.Trim();
        }
    }
}